using Cysharp.Threading.Tasks;
using IQIGame.Onigao.Framework;
using IQIGame.Onigao.Game;
using System.Collections.Generic;
using UnityEngine;

namespace IQIGame.Onigao.GamePlay
{
    /// <summary>
    /// 需要自行管理EntityGroup时使用
    /// 可以提供一些方便的接口，例如直接显示到挂点上
    /// 特效管理建议都继承这个
    /// </summary>
    public abstract class TEntityGroupCtrl : TModuleController
    {
        public abstract EntityPoolGroupType groupType { get; }
        private EntityGroup _entityViewPool;
        /// <summary>
        /// object索引
        /// </summary>
        private HashSet<Entity> _entityViews = new();

        protected override void OnModuleGameplayInit()
        {
            ManagerCenter.Entity.EnableGroup((int)groupType);
            _entityViewPool = ManagerCenter.Entity.GetEntityGroup((int)groupType);
        }

        protected override void OnSceneLoaded()
        {

        }

        private Entity CreateEntity(string effectPath)
        {
            var effectUnit = ManagerCenter.Entity.Get(effectPath, _entityViewPool);
            return effectUnit;
        }

        public UniTask<Entity> ShowEntity(TEntity entity, EntityBindPointCommonType bindPointId, int resCid, Vector3 offset = default)
        {
            var cfgResource = TableCenter.resource.Get(resCid);
            return ShowEntity(entity, bindPointId, cfgResource.Url, offset);
        }

        public async UniTask<Entity> ShowEntity(TEntity entity, EntityBindPointCommonType bindPointId, string effectPath, Vector3 offset = default)
        {
            var bindPointCom = entity.AddComponentWithPool<EntityBindPointComponent>(ETComponentType.EntityBindPoint);
            if (bindPointCom == null)
            {
                LogGame.LogError("entity上找不到EntityBindPointComponent。");
                return null;
            }
            var bindPointTransform = bindPointCom.GetBindPoint(bindPointId);
            return await ShowEntity(bindPointTransform, effectPath, offset);
        }

        public UniTask<Entity> ShowEntity(Transform bindPointTrans, int resCid, Vector3 offset)
        {
            var cfgResource = TableCenter.resource.Get(resCid);
            return ShowEntity(bindPointTrans, cfgResource.Url, offset);
        }

        public async UniTask<Entity> ShowEntity(Transform bindPointTrans, string effectPath, Vector3 offset)
        {
            var effectEntity = CreateEntity(effectPath);
            await effectEntity.Load();

            if (!effectEntity.isLoaded)
            {
                return null;
            }
            _entityViews.Add(effectEntity);

            var transform = effectEntity.gameObject.transform;
            transform.SetParent(bindPointTrans, false);
            transform.localPosition = offset;

            return effectEntity;
        }

        public virtual void HideEntity(Entity effect)
        {
            if (effect == null)
            {
                return;
            }
            _entityViews.Remove(effect);
            _entityViewPool.HideEntity(effect);
        }

        protected override void OnDispose()
        {
            //这里直接遍历Hide，这样可以将一个GroupType用到不同的Controller里，按Controller释放
            //否则如果直接调用_effectPool.HideAll()是按GroupType整个释放，要求每个不同的系统必须使用不同的GroupType
            //建议按GroupType严格分开，这里这么做只是为了最大限度容错
            foreach (var effect in _entityViews)
            {
                _entityViewPool.HideEntity(effect);
            }
            _entityViews.Clear();
            ManagerCenter.Entity.DisableGroup((int)groupType);
        }
    }
}
